package com.cell.service.order.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;

import com.cell.common.States;
import com.cell.common.exceptions.exceptions.OrderException;
import com.cell.dao.order.OrderDao;
import com.cell.dao.order.OrderDetailDao;
import com.cell.dao.order.OrderStatesDao;
import com.cell.dao.recycable.RecyclableNameDao;
import com.cell.dao.recycable.RecyclableTypeDao;
import com.cell.dao.user.UserDao;
import com.cell.dao.user.location.LocationDetailDao;
import com.cell.dao.user.location.UserLocationDao;
import com.cell.pojo.VO.order.AgentOrderVO;
import com.cell.pojo.VO.order.UserOrderVO;
import com.cell.pojo.entity.order.Order;
import com.cell.pojo.entity.order.OrderDetail;
import com.cell.pojo.entity.order.OrderStates;
import com.cell.pojo.entity.recyclable.RecyclableName;
import com.cell.pojo.entity.recyclable.RecyclableType;
import com.cell.pojo.entity.user.User;
import com.cell.pojo.entity.user.location.LocationDetail;
import com.cell.pojo.entity.user.location.UserLocation;
import com.cell.service.order.IOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cell.service.user.IUserService;
import com.tencentcloudapi.bda.v20200324.models.Age;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类 yyf
 * </p>
 *
 * @author cloudJiang
 * @since 2022-06-04
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements IOrderService {
    @Autowired
    OrderDao orderDao;
    @Autowired
    OrderDetailDao orderDetailDao;
    @Autowired
    OrderStatesDao orderStatesDao;
    @Autowired
    RecyclableNameDao recyclableNameDao;
    @Autowired
    RecyclableTypeDao recyclableTypeDao;
    @Autowired
    UserLocationDao locationDao;
    @Autowired
    LocationDetailDao locationDetailDao;
    @Autowired
    UserDao userDao;
    @Autowired
    IUserService userService;

    @Override
    public void overOrder(Long id, BigDecimal weight) {
        /**
         * 根据传进来的id,改变状态为2，计算出总价格
         */
        //根据id查询得到statesId,detailId
        Order order = orderDao.selectById(id);
        if (order == null) {
            throw new OrderException(States.ERR_SELECT.getStates(), "查询数据失败，请检查参数id");
        }
        Long statesId = order.getStatesId();
        Long detailId = order.getDetailId();
        int state = 2;
        //通过statesid改变状态为2
        UpdateWrapper<OrderStates> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", statesId);
        OrderStates orderStates = new OrderStates();
        orderStates.setStates(2);
        int update = orderStatesDao.update(orderStates, updateWrapper);
        if (update != 1) {
            throw new OrderException(States.ERR_UPDATE.getStates(), "更新数据失败，请稍后再试");
        }
        //通过detailid查询到recNameId
        OrderDetail orderDetail = orderDetailDao.selectById(detailId);
        if (orderDetail == null) {
            throw new OrderException(States.ERR_SELECT.getStates(), "查询数据失败，请检查参数id");
        }
        Integer recNameId = orderDetail.getRecNameId();
        //通过recNameId查询到商品price
        RecyclableName recyclableName = recyclableNameDao.selectById(recNameId);
        if (recyclableName == null) {
            throw new OrderException(States.ERR_SELECT.getStates(), "查询数据失败，请检查参数id");
        }
        BigDecimal price = recyclableName.getPrice();
        //weight*price获取总价格totalPrice
        BigDecimal totalPrice = weight.multiply(price);
        //更改totalPrice
        UpdateWrapper<OrderDetail> updatePrice = new UpdateWrapper<>();
        updatePrice.eq("id", detailId);
        OrderDetail orderDetail1 = new OrderDetail();
        orderDetail1.setWeight(weight);
        orderDetail1.setTotalPrice(totalPrice);
        int updateweightandtPrice = orderDetailDao.update(orderDetail1, updatePrice);
        if (updateweightandtPrice != 1) {
            throw new OrderException(States.ERR_UPDATE.getStates(), "更新数据失败，请稍后再试");
        }
    }

    @Override
    public void endOrder(Long id) {
        if (id == null) {
            throw new OrderException(States.ERR_BAD_REQUEST.getStates(), "参数不能为null");
        }
        Order order = orderDao.selectById(id);
        if (order == null) {
            throw new OrderException(States.ERR_SELECT.getStates(), "查询数据失败，请检查参数id");
        }
        Long statesId = order.getStatesId();
        UpdateWrapper<OrderStates> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", statesId);
        updateWrapper.eq("states", 2);
        OrderStates orderStates = new OrderStates();
        orderStates.setStates(3);
        LocalDateTime now = LocalDateTime.now();
        orderStates.setEndTime(now);
        int rows = orderStatesDao.update(orderStates, updateWrapper);
        if (rows != 1) {
            throw new OrderException(States.ERR_UPDATE.getStates(), "更新数据失败，请稍后再试");
        }
    }

    @Override
    public void acceptOrder(Long id, Long buyId) {
        if (id == null || buyId == null) {
            throw new OrderException(States.ERR_BAD_REQUEST.getStates(), "参数不能为null");
        }
        //通过给出的id查询订单
        Order order = orderDao.selectById(id);
        if (order == null) {
            throw new OrderException(States.ERR_SELECT.getStates(), "查询数据失败，请检查参数id");
        }
        order.setBuyId(buyId);
        int i = orderDao.updateById(order);
        if (i != 1) {
            throw new OrderException(States.ERR_UPDATE.getStates(), "更新数据失败，请稍后再试");
        }
        Long statesId = order.getStatesId();
        UpdateWrapper<OrderStates> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", statesId);
        OrderStates orderStates = new OrderStates();
        LocalDateTime now = LocalDateTime.now();
        orderStates.setStates(1);
        orderStates.setStartTime(now);
        orderStates.setEndTime(now.plusDays(15));
        int update = orderStatesDao.update(orderStates, updateWrapper);
        if (update != 1) {
            throw new OrderException(States.ERR_UPDATE.getStates(), "更新数据失败，请稍后再试");
        }
    }

    @Override
    public void commitErrorOrder(Long id, String errorMessage) {
        //获取传输进来的订单号
        if (errorMessage.isEmpty() || id == null) {
            throw new OrderException(States.ERR_BAD_REQUEST.getStates(), "参数不能为null");
        }
        Order order = orderDao.selectById(id);
        //如果获取的查询数据为空，返回1
        if (order == null) {
            throw new OrderException(States.ERR_SELECT.getStates(), "查询数据失败，请检查参数id");
        }
        //获取statesId,更改状态为4
        Long statesId = order.getStatesId();
        UpdateWrapper<OrderStates> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", statesId);
        OrderStates orderStates = new OrderStates();
        orderStates.setStates(4);
        orderStates.setErrorMessage(errorMessage);
        int update = orderStatesDao.update(orderStates, updateWrapper);
        if (update != 1) {
            throw new OrderException(States.ERR_UPDATE.getStates(), "更新数据失败，请稍后再试");
        }
    }

    /**
     * 用户第一次发布订单，此时订单状态为0待接单
     *
     * @param weight 卖家填写大概重量
     * @param type   回收物品类型
     * @param name   回收物品名称
     * @return 成功返回0, 否则返回1
     */
    @Override
    public void commitOrder(Long salId, String name, String type, BigDecimal weight) {
        //卖家提供买家给出的物品类型，物品种类，获取他们的id,插入一个tb_order_detail表
        if (salId == null || name.isEmpty() || type.isEmpty() || weight == null) {
            throw new OrderException(States.ERR_BAD_REQUEST.getStates(), "参数不能为null");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        List<RecyclableName> recyclable = recyclableNameDao.selectByMap(map);
        if (recyclable == null) {
            throw new OrderException(States.ERR_SELECT.getStates(), "查询数据失败，请检查参数id");
        }
        RecyclableName recyclableName = recyclable.get(0);
        //获取查询到的nameId 和typeId和价格
        Integer id = recyclableName.getId();
        Integer typeId = recyclableName.getTypeId();
        BigDecimal price = recyclableName.getPrice();
        //计算出总价格
        BigDecimal totalPrice = price.multiply(weight);
        //生成新的detail表
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setRecNameId(id);
        orderDetail.setRecTypeId(typeId);
        orderDetail.setWeight(weight);
        orderDetail.setTotalPrice(totalPrice);
        int insertdetail = orderDetailDao.insert(orderDetail);
        if (insertdetail != 1) {
            throw new OrderException(States.ERR_SELECT.getStates(), "插入数据失败，请稍后再试");
        }
        //生成新的order_states表
        OrderStates orderStates = new OrderStates();
        //当前订单状态为0
        orderStates.setStates(0);
        orderStatesDao.insert(orderStates);
        //获取order表里面需要的statesId和detailId
        Long statesId = orderStates.getId();
        Long detailId = orderDetail.getId();
        Order order = new Order();
        order.setSalId(salId);
        order.setStatesId(statesId);
        order.setDetailId(detailId);
        int insert = orderDao.insert(order);
        if (insert != 1) {
            throw new OrderException(States.ERR_SELECT.getStates(), "插入数据失败，请稍后再试");
        }
    }

    @Override
    public List<UserOrderVO> getAllOrder(Integer states, Long userId) {
        if (states == null || userId == null) {
            throw new OrderException(States.ERR_BAD_REQUEST.getStates(), "参数不能为null");
        }
        List<Order> orders = orderDao.selectstatesIdByuserid(userId);
        if (orders.isEmpty()) {
            throw new OrderException(States.ERR_SELECT.getStates(), "没有查询到符合该条件的订单信息" +
                    "请换一个条件试试");
        }
        for (Order order : orders) {
            Long statesId = order.getStatesId();
            Map<String, Object> map = new HashMap<>();
            map.put("Id", statesId);
            map.put("states", states);
            List<OrderStates> orderStates = orderStatesDao.selectByMap(map);
            for (OrderStates orderStates1 : orderStates) {
                int state = orderStates1.getStates();
                Long statesIds = orderStates1.getId();
                Map<String, Object> map1 = new HashMap<>();
                map1.put("states_id", statesIds);
                List<Order> orderdetail = orderDao.selectByMap(map1);
                if (orderdetail == null) {
                    throw new OrderException(States.ERR_SELECT.getStates(), "查询数据失败，请检查参数");
                }
                UserOrderVO userOrderVO = new UserOrderVO();
                List<UserOrderVO> orderVOList = new ArrayList<>();
                for (Order order1 : orderdetail) {
                    //判断要查询的是卖方id还是买房id
                    if (userId.equals(order1.getSalId())) {
                        Long buyId = order1.getBuyId();
                        User user = userDao.selectById(buyId);
                        String username = user.getUserName();
                        userOrderVO.setUserName(username);
                    } else if (userId.equals(order1.getBuyId())) {
                        Long salId = order1.getSalId();
                        User user = userDao.selectById(salId);
                        String username = user.getUserName();
                        userOrderVO.setUserName(username);
                    }
                    userOrderVO.setState(state);
                    //查出statrttime和endtime并赋值给vo
                    Long statesId1 = order1.getStatesId();
                    OrderStates orderStates2 = orderStatesDao.selectById(statesId1);
                    BeanUtils.copyProperties(orderStates2, userOrderVO);

                    //取出weight和totalPrice赋值给vo
                    Long detailId = order1.getDetailId();
                    OrderDetail orderDetail = orderDetailDao.selectById(detailId);
                    BeanUtils.copyProperties(orderDetail, userOrderVO);

                    //取出商品名称和商品种类id并赋值给vo
                    int recNameId = orderDetail.getRecNameId();
                    int recTypeId = orderDetail.getRecTypeId();
                    RecyclableName recyclableName = recyclableNameDao.selectById(recNameId);
                    RecyclableType recyclableType = recyclableTypeDao.selectById(recTypeId);
                    String name = recyclableName.getName();
                    String type = recyclableType.getTypeName();
                    BigDecimal price = recyclableName.getPrice();
                    userOrderVO.setRecyclableName(name);
                    userOrderVO.setRecyclableType(type);
                    userOrderVO.setPrice(price);
                    orderVOList.add(userOrderVO);
                }
                return orderVOList;
            }
        }
        return null;
    }

    @Override
    public void deleteOrderByAdmin(Long orderID) {
        userDao.deleteOrderByAdmin(orderID);
    }

    @Override
    public List<AgentOrderVO> getNearbyOrder(Integer userState, Long locationId) {
        List<AgentOrderVO> returnList = new ArrayList<>();
        List<User> nearByUsers = new ArrayList<>();
        UserLocation userLocation = locationDao.selectById(locationId);
        LocationDetail locationDetail = locationDetailDao.selectById(userLocation.getDetailId());
        //根据代理等级来选择查找订单范围，等级越高范围越大
        if (userState == 3) {
            nearByUsers = userService.getUsersFromCity(userLocation.getProvinceId(), userLocation.getCityName());
        } else if (userState == 2) {
            nearByUsers = userService.getUsersFromDetail(userLocation.getProvinceId(), userLocation.getCityName(),
                    locationDetail.getDistrict(), "");
        } else {
            nearByUsers = userService.getUsersFromDetail(userLocation.getProvinceId(), userLocation.getCityName(),
                    locationDetail.getDistrict(), locationDetail.getCommunity());
        }

        for (User u : nearByUsers) {
            //查找附近用户提交的订单
            List<Order> orders = orderDao.selectPostOrder(u.getId());
            //获取用户位置信息
            UserLocation userLocation1 = locationDao.selectById(u.getLocationId());
            LocationDetail locationDetail1 = locationDetailDao.selectById(userLocation1.getDetailId());
            for (Order order : orders) {
                //获取此订单相关信息
                OrderDetail detail = orderDetailDao.selectById(order.getDetailId());
                OrderStates states = orderStatesDao.selectById(order.getStatesId());

                //组织vo
                AgentOrderVO agentOrderVO = new AgentOrderVO();
                agentOrderVO.setOrderId(order.getId());
                agentOrderVO.setPostUserName(u.getUserName());
                agentOrderVO.setState(states.getStates());
                agentOrderVO.setDistrict(userLocation1.getCityName() + locationDetail1.getDistrict()
                        + locationDetail1.getCommunity());
                agentOrderVO.setRecyclableType(recyclableTypeDao.selectById(detail.getRecTypeId()).getTypeName());
                agentOrderVO.setRecyclableName(recyclableNameDao.selectById(detail.getRecNameId()).getName());
                agentOrderVO.setWeight(detail.getWeight());
                agentOrderVO.setPrice(detail.getTotalPrice());

                //将vo添加到返回集
                returnList.add(agentOrderVO);
            }
        }

        return returnList;
    }

    @Override
    public void deleteOrder(Long orderID) {
        if (orderID == null) {
            throw new OrderException(States.ERR_BAD_REQUEST.getStates(), "参数不能为null");
        }
        userDao.deleteOrder(orderID);
    }
}
